package com.ayitubie.gateway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import reactor.core.publisher.Flux;
import java.net.URI;
import java.nio.charset.StandardCharsets;

//@Configuration
public class EncryptionFilterConfig {

    @Autowired
    CryptoUtil cryptoUtil;
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter encryptionFilter() {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String method = request.getMethodValue();
            String url = request.getPath().value();
            if ("POST".equals(method)) {
                if("/user/login".equals(url)){
                    return DataBufferUtils.join(request.getBody())
                            .flatMap(dataBuffer -> {
                                byte[] bytes = new byte[dataBuffer.readableByteCount()];
                                dataBuffer.read(bytes);
                                DataBufferUtils.release(dataBuffer);
                                String body = new String(bytes, StandardCharsets.UTF_8);
                                String decryptedBody = cryptoUtil.desEncrypt(body);
                                byte[] decryptedBytes = decryptedBody.getBytes(StandardCharsets.UTF_8);

                                ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(request) {
                                    @Override
                                    public Flux<DataBuffer> getBody() {
                                        return Flux.just(exchange.getResponse().bufferFactory().wrap(decryptedBytes));
                                    }
                                };
                                return chain.filter(exchange.mutate().request(mutatedRequest).build());
                            });
                }
            }
            return chain.filter(exchange);
        };
    }
}
